#ifndef FILE_INFO_HPP
#define FILE_INFO_HPP

#include <fstream>
#include <map>
#include <string>
#include <vector>
#include <boost/ptr_container/ptr_vector.hpp>

/**
 * FileInfo should be used get information on one file (number of different word, total number of word, ...)
*/
class FileInfo 
{
	protected : 
		/** words->numberOfOccurences **/
		std::map <std::string, int> wordsNumber; 

		/** total number of words (two time a same word will count as 2) **/
		int numberOfWords;

		/** fileName **/
		std::string fileName;

		/** word to be filter **/
		static const std::string wordFilter[];

		/** filter words which are less than three letters or which are in the list wordList
         *  (or both...)
 		 * @return true if the words should be kept, false either 
		**/
		bool filter(const std::string& word);

		/**
		 * read the given stream word by word and add it to the wordsNumber map
		**/
		void read(std::ifstream& stream);
	
	public : 
		/** 
		  * construct a fileInfo 
		  * @param filePath the path of the file to get info on
		**/
		FileInfo(std::string const& filePath);

		/** 
		 * destruct a fileInfo
		**/
		~FileInfo();

		/**
		 * get the number of time a word appear in the document
		 * @param word the word to get the number of occurences 
		 * @return the number of time the given word appear in the document
		**/
		int getOccurences(std::string word)
		{ return (wordsNumber.find(word) == wordsNumber.end() )? 0:wordsNumber[word];}

		/** 
		 * get the number of different words that appears in the document
		 * @return the number of different words that appears in the document (two time the same word count as 1
		**/
		int getNumberOfDifferentWords()
		{return this->wordsNumber.size();}

		/**	
		 * get the total number of word in the document
		 * @return the number of word in the document (two time the same word count as 2)
		**/
		int getNumberOfWords()
		{return this->numberOfWords;}

		/**
		 * @return the path of the file given in the constructor
		**/
		std::string getFilePath()
		{ return fileName;}
};

class CorpusInfo
{
	protected : 
		/** list of FileInfo : 1 for each text of the corpus **/
		boost::ptr_vector<FileInfo> filesInfo;

		/** protected copy **/
		CorpusInfo(const CorpusInfo&){}

	public :
		/**
		 * construct a corpus info from a vector of filenames
		**/
		CorpusInfo(std::vector<std::string> files);

		/**
		 * construct a corpus info from an array of filenames of size size
		**/
		CorpusInfo(std::string files[], unsigned int size);

		/**
		 * construct a empty corpos info
		 */
		CorpusInfo();

		/**
		 * add a document to a corpus info
		 */
		void addDocument(const std::string& file);

		~CorpusInfo();

		/**
		 * @param word the word 
		 * @param fileIndex the index of the file 
		 * @return tf/idf word of the fileIndex/word
		*/
		double tfIdf(std::string const& word, int fileIndex);

		/**
		 * @param word the word
		 * @param fileIndex the index of the file 
		 * @return tf of the fileIndex/word
		**/
		double tf(std::string const& word, int fileIndex);
	
		/**
		 * @param word the word
		 * @param fileIndex the index of the file 
		 * @return idf of the fileIndex/word
		**/
		double idf(std::string const& word);

	  	/**
		 * @return the number of file in the corpus
		**/
		int getNumberOfFile()
		{ return filesInfo.size();}
	
		/**
		 * @return the FileInfo at the given index
		**/
		FileInfo& getFileInfo(int index)
		{return filesInfo[index];}
};

#endif

